I've got a page which returns
X-Drupal-Dynamic-Cache: UNCACHEABLE, I've got a suspicion that this is related to a view that is embedded in the page. Though, this made me wonder; is there any way to see what invalidated actually the page cache?
As suggested in the answer from CG Monroe, enabling the header will show you what contexts you have, a user or session cache context can for example disable caching as well as a max-age 0.
Tracking down exactly where they are coming from can be tricky, I usually debug on the merge methods of the Cache class with a breakpoint set on having the problematic context/age. Certain filters/sorts or so (e.g. a random sort) can cause this, but so can certain block conditions (there is actually a known issue with that, see https://www.drupal.org/project/drupal/issues/2521956).
The X-Drupal-Cache-Tags header should help with this. Here's how to enable it from this doc:
You can debug cacheable responses (responses that implement this interface, which may be cached by Page Cache or Dynamic Page Cache) by setting the http.response.debug_cacheability_headers container parameter to true, in your services.yml. Followed by a container rebuild, which is necessary when changing a container parameter.
That will cause Drupal to send X-Drupal-Cache-Tags and X-Drupal-Cache-Contexts headers.