I provide a library with its header files to a user.
I often release new versions, minors and majors.
Sometimes the user still uses an old version of the header files and somehow he still can link the shared library against it.
Changes are made internally and on the API but on things he doesn't seem to use, therefore I believe the linker still thinks it's valid.
How can I version so that I'm 100% sure the user will use the correct header files with the library?
I'm not 100% sure the problem is this one, but it's just a question.
The short response is, you can't. But, with some awareness it can be done. Take a look ad SOLID principle, it is the way to create a stable API, which gives you sufficient flexibility to modify your application, at the same time not breaking the binary backward compatibility and disturbing others.
What you should expose? I would recommend to expose functions and interfaces only. Everything else comes with the risk of breaking the binary backward compatibility. Expose only the functions and interfaces required by that particular client. The client should not be aware of your internal changes, or of changes for other clients. In this case externals will be changed usually rarely, but if changed, it will lead to compile errors and users will be forced to fix them.
If you want to expose structures and classes, then you got a problem there. Make a clear policy to not expose structures and classes. It still might be not an option, so make a clear policy of not changing them on random circumstances. These changes will cost you too much. But if still you require to change them, first of all rethink carefully the architecture then perform these changes in a centralized way.