Dynamic websites

Static websites seem simple, but it is hard to avoid breaking things even with those (see web design checklist). Dynamic ones are certainly more complex, and there's more things to break and/or overcomplicate. Below is an outline of relatively basic technologies and tools that are sufficient for building a typical dynamic website.

DBMS
Most of the dynamic websites are essentially custom database interfaces. Advanced DBMSes such as PostgreSQL provide extensive tooling for access control and business logic implementation: see Database Roles, GRANT, Row Security Policies, Constraints, Server Programming. With a properly designed database, a typical dynamic website only has to serve as a bridge between a database and a web server. In case of PostgreSQL, libpq is the client library, and bindings to it are usually available. Though when a project is small enough, it may be better to store structured files directly, without a DBMS.
CGI
CGI provides a simple interface between a web server and an application. It can be used without any specialised libraries (for instance, as implemented in bwchat), though more convenient with those. There is FastCGI, an almost drop-in alternative useful for optimisation. Web servers such as nginx (which provide plenty of nice related functionality), and possibly fcgiwrap, are the relevant software here. Among the libraries are Perl's CGI.pm, Haskell's cgi and fastcgi libraries.
HTML forms
HTML forms specify how to serialise data for GET (where form data goes into URI query, QUERY_STRING in CGI) and POST (where form data goes into HTTP message body, usually stdin with CGI) requests. application/x-www-form-urlencoded can be (and often is) used for both, though form's enctype can be changed for POST requests to use multipart/form-data. Parsing of "urlencoded" data is easy to implement even in place, while "multipart" parsing may better be done with a library, though not sure if there are any prominent ones to highlight.
HTML templates
I used to include XSLT for HTML templating here, which integrates nicely with XHTML (or HTML 5's XML syntax) on one side and DBMS-produced XML on the other, but since the XML-based syntax is being phased out in HTML LS (see my HTML notes for more on that), and XSLT produces a slightly incorrect HTML in its HTML mode, it may be worthwhile to consider other options now: possibly something like m4, or HTML without templating, composed as a string.
HTTP authentication
Standard HTTP authentication mechanisms include password-based authentication, which is bearable when used over TLS. The "Basic" scheme is trivial to handle with CGI by base64-decoding HTTP_AUTHORIZATION, and using the login and password directly for, for instance, DBMS authentication. Base64 is easy to decode, can be implemented in-place fairly easily, and widely supported. But it can also be handled by a generic web server, such as nginx. Not well-supported by most web browsers though: usually there is not mechanism to forget or alter credentials, and their handling with embedded objects and JS-based requests varies from browser to browser.
File manipulation
WebDAV does not integrate with plain HTML forms, but provides capabilities for file manipulation, and can be useful for HTTP-based APIs (possibly used by UIs other than web browsers working with plain HTML), and can be handled by generic software (e.g., nginx's http_dav module). Among other things, one may process uploaded files asynchronously with inotify(7) (inotify-tools, systemd.path).
SQL
Unless a project is small and well-defined (and stays that way), it quickly becomes cumbersome to map different combinations of parameters into SQL queries. A simpler approach is to read a query template from a parameter, and substitute other parameters into it (as I implemented in pg×html). Potential slow custom queries can be dealt with using timeouts and/or per-user time quotas. As another way to provide a generic interface to the database, PostgREST is useful for an HTTP-and-JSON-based interface, though for web UIs, it aims JS-based ones.

While some dynamic websites may require different or additional technologies (e.g., SPARQL instead of SQL, not an RDBMS at all, or it may be crucial to adorn an authentication form), the described tools would cover many cases, while keeping things relatively simple. These are nice tools to use, avoiding unnecessary abstractions on top of other abstractions, and/or reimplementation of essentially the same things over and over again.