Look into Blueprints equivalent of structs. A single struct variable can hold a LOT of user defined data - everything there is to know about the player, for example. Then you save / load just that one variable.
Conversely, everything there is to know about an enemy could be held in the Enemy struct, and if you need to save / load a whole bunch of those, you add them to an array - still only one variable to load / save. Unless you have arrays of arrays of arrays of… - which you will almost always have anyway 
There is some upfront work to be done, of course, and working with structs will be finicky - they’re fussy at times.
Operating on structs is often done with SetMembers node:
You expose what’s needed, modify it, and that particular float spends its life inside the struct rather than as a separate variable. And you can nest structs inside of structs (it does complicate iteration, though):
Technically speaking, you could save the entire game inside a single struct. But that’s not really feasible for anything beyond tiny in scope.
When it comes to displaying stats, widgets take advantage of structs:

Above, a widget’s text block fetches values from a nested struct. This would also work if you provided the widget with a reference to the player - this way you do not need to manually copy / update the struct. Blueprints copy enough data as is.
The native system is as straightforward as it is limited. That’s why such plugins exist:

