I think basically using TPageControl and several forms consume roughly the same memory usage. Because if you add a form in Lazarus, it will be (set to) auto-created when program start and closing a form will not really freeing the form. Unless you manually change the 'behavior'.
However, creating forms dynamically, and freeing them when no longer needed to minimise memory load for large objects is usually much easier than creating tabsheets dynamically and inserting them into and later removing them from a pagecontrol (though it can be done). This also has the disadvantage that it is very non-standard behaviour, even if it reduces overall memory use.
Users don't expect page control tabs to disappear with no obvious way to get them back again.
Whereas users are usually very familiar with modal dialogs (forms) that are dismissed when they have served their purpose.
Could there be a way to load the content of each page only when the user selects the corresponding tabsheet?
Yes, you can. By using OnChange and/or OnChanging. I haven't tried but it should be something like this: load the image in OnChange event and freeing it on the OnChanging event.
You would have to use OnChanging, since that anticipates the showing of the new page. If you wait until OnChange to add GUI content the next tabsheet is already shown, and you would probably get odd effects, flicker or worse, depending on the widgetset.