The code given in the linked answer as you rightfully point out only works in Blender 2.80. I cannot find the source at the moment, but I read somewhere that __annotations__ have been added to Blender 2.80 for exactly the reason you are trying to use it: So that a user can conveniently check out custom added properties that came from Add-ons. There is no true replacement for that in Blender 2.79, the feature simply did not exist.
Other methods can get you a long way though. The given code example can be changed to this:
def my_function(self, context): first_scene = bpy.context.scene ### new scene creation comes before the loop: new_scene= bpy.data.scenes.new("New scene") context.window.scene = new_scene ### copy attributes from source to target scene: for key in first_scene.scene_prop.bl_rna.properties.keys(): source_attribute = getattr(first_scene.scene_prop, key) ### copy attribute only if it can be written ### bl_rna.properties returns more props than you defined yourself ### one example is 'rna_type', which is write protected ### so use the .is_property_readonly() method that each prop offers to check this if not first_scene.scene_prop.is_property_readonly(key): setattr(new_scene.scene_prop, key, source_attribute)
There are only two major differences here. One is that the property string list is retrieved using .bl_rna.properties.keys(). You will see .bl_rna on most corners of Blender Python, it is a way of inspecting the internals of the current Python object you are dealing with. Most commonly you will then use the properties path from there (as we do in this code example) to get to the custom defined properties.
The problem we are facing now is, we also get additional ones that were created by Blender itself. rna_type is a common one, I've seen others as well though. Some of these properties, like the mentioned rna_type, are write protected. That's where the second change comes in: Your custom scene_prop has a method called .is_property_readonly(), which needs a string passed on to it - the key we just retrieved. So the if-clause makes sure we just try to set the prop if it can be written.