There are many articles out there attempting to define and describe headless CMS. When I was drawing a diagram (in PowerPoint... because that's where I draw diagrams these days...) for a client to show a headless architecture vs. traditional/coupled architecture, I realized the primary differentiator is one thing. All of the latest and greatest "new" cloud-native headless CMSes will say that to be a real headless CMS you need all of these other things (cloud-native, headless first, developer-driven, blah blah blah), but architecturally, it's really just about data flow.
A headless CMS is one in which the head - an experience implementation (e.g. could be a website or mobile app codebase) - reaches backwards and fetches content from the CMS, as opposed to the CMS pushing content into the experience.
Please allow my PowerPoint diagrams to illustrate this:
As you can see in the diagram above, a traditional CMS will run the website in the same application as the CMS itself. It's a single "package" when it comes to hosting. A request to the website comes to the CMS part of the application and it "pushes out" a server-side response with the website code hydrated with CMS-managed content.
And a headless/decoupled CMS will run the website itself in the separate application from the CMS. A request to the website hits the custom application, and it then decides if it needs to fetch content -- if so, it dispatches API calls to the CMS. In the case of static site generation (SSG), it ends at the custom app since the CMS content is hydrated into the custom app at build not, not runtime.