Thanks for the in-depth answer @dieter
We're using Plone 5.0.7 with plone.app.multilingual 5.0.3
The folder structure is explained here GitHub - plone/plone.app.multilingual: Plone Multilingual Content Add-on
The "active" language negotiation itself is not handled by plone.app.multilingual but by the plone.i18n.negotiator module. I should have paid more attention to the introduction section of https://docs.plone.org/develop/plone/i18n/language.html - namely: "Language is negotiated at the beginning of the page view."
Also noticing there is likely an error on that page: a reference to Products.PloneLanguageTool. It seems the tool was made part of plone.i18n in version 3.0.0 (2015-03-26).
I think I may understand why in my workaround all translated strings were in the language of the first document. Looking here: plone.i18n/plone/i18n/utility.py at master · plone/plone.i18n · GitHub
binding = request.get('LANGUAGE_TOOL', None)
if not isinstance(binding, LanguageBinding):
# Not bound -> bind
setLanguageBinding(request)
binding = request.get('LANGUAGE_TOOL')
This creates a new language binding when called the first time around...