How can I store and retrieve a custom list in a blend file?
Part of the confusion with my question came from the fact I presumed that defining an EnumProperty was the correct, and only, way to store a list.

What I didn't quite understand was that the CollectionProperty itself would act like a list. I can have much the same code as I had before, minus the enum:

class customPropertiesGroup(bpy.types.PropertyGroup):
    customString = bpy.props.StringProperty()
bpy.utils.register_class(customPropertiesGroup)

bpy.types.Scene.customLists = bpy.props.CollectionProperty(type=customPropertiesGroup)


And every time I want to add a new item I do:

newCustomItem = bpy.context.scene.customLists.add()
newCustomItem.customString = "test1"
newCustomItem = bpy.context.scene.customLists.add()
newCustomItem.customString = "test2"
etc..


I can then access each custom item with:

bpy.context.scene.customLists[0].customString
bpy.context.scene.customLists[1].customString


If I want nested lists I can simply have the PropertyGroup Class' property as another CollectionProperty:

class subcustomPropertiesGroup(bpy.types.PropertyGroup):
    customString = bpy.props.StringProperty()
bpy.utils.register_class(subcustomPropertiesGroup)

class customPropertiesGroup(bpy.types.PropertyGroup):
    subLists = bpy.props.CollectionProperty(type=subcustomPropertiesGroup)    
bpy.utils.register_class(customPropertiesGroup)

bpy.types.Scene.customLists = bpy.props.CollectionProperty(type=customPropertiesGroup)

newcustomList = bpy.context.scene.customLists.add()
newcustomList.name= "List 1"
newSubList = bpy.context.scene.customLists["List 1"].subLists.add()
newSubList.name = "Sub List 1"
newSubList.customString = "String 1"


This allows me to have an arrangement where I can access lists and sublists like so:

bpy.context.scene.customLists['List 1'].subList['Sub List 1'].customString


I can add or remove items (with customLists.remove(index)) and print them out like I would a normal python list:

for customList in bpy.context.scene.customLists:

    print("List: "+customList.name)

    for subList in customList.subLists:

        print("Sub List: "+subList.name)
        print("Custom property: "+subList.customString)


And because I am not clearing the list each time I define it (as I was in the question) the properties become available again after reloading the file and re-running the code.