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.
CGI
CGI provides a simple interface between a web server and an application. It is very easy to use without any specialised libraries, though 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.
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.
XSLT
HTML 5 includes two concrete syntaxes, one of which is XML-based (similar to XHTML). Some DBMSes (such as PostgreSQL, again) are capable of serialising query results into XML at once, for others it's still trivial to do so, possibly in a generic way. While XSLT is there to transform some XML documents (e.g., query results) into others (e.g., HTML, or even non-XML ones, such as plain text), and can be applied anywhere from a DBMS to a web browser. libxml2 (along with libxslt for transformations and libexslt for URL encoding) is a good library for that.
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 DBMS authentication. Base64 is easy to decode, and there's plenty of libraries.
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. Potential slow custom queries can be dealt with using timeouts and/or per-user time quotas.

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), even this exact combination would cover many cases, while keeping things 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.

I wrote pg×html to combine those roughly as described here, so that remaining website-specific bits are minimal: a database schema and templates, possibly httpd configuration.

I find CGI.pm to be handy as well: it's not new or fancy, and in Perl (which is not my favourite language), but quite polished, widely available (and a Perl interpreter is usually already installed even on minimalistic systems), easy to use. I'd probably read that with scepticism a few years ago, assuming that the article is either from late 90s or early 2000s, or by somebody who was just stuck with Perl since then, but some of the old technologies turn out to be rather nice.