We run Pyramid via uwsgi, behind an OpenResty server (Nginx fork with embedded lua interpreter).
IMHO the "best" stack is somewhat dependent on your application. We have a large application and the forking model of uwsgi - combined with many of its management hooks - lets us aggressively leverage a lot of efficiencies via the copy-on-write memory behavior. gunicorn was not nearly as performant for us with our core app, however it has been more performant on other apps. We've run some smaller apps via waitress as a test, and forgot about it for months - it worked perfectly with no complaints.
Caddy is certainly a decent server - and has some of the best https termination and ssl certificate management in the field. It has a built in ACME client, and can store provisioned certificates in the cloud, which simplifies a lot of devops in clustered environments.
I stay away from Apache and personally don't recommend it. Nginx (and caddy) is far better with concurrent requests and throughput; they also have much lighter memory footprints. We can run a lot more uwsgi processes behind Nginx than any Apache deployment option - which means we can scale to more processes on a node before having to scale onto more nodes in a cluster. In my experience, from a devops management and billing perspective, Apache tends to be much more expensive.