Solutions 1 and 2 correctly solve your immediate problem. I want to be more general about collections.
As you've surmised, removing an item from a collection does not destroy that item – .Net collections do not 'take ownership' of items you put into them. This is generally a good thing, as you will have references elsewhere and those should remain valid (and if you don't, the item will go out of scope anyway and be destroyed in a GC cycle). However, with UI elements, the framework maintains references to them so they don't go out of scope and your application can lose track of them.
If you use a list class which implements INotifyCollectionChanged (i.e. ObservableCollection<Form>) or IBindingList (e.g. BindingList<T>), there is an event when the collection is changed. But for List<T> (what you should use by default for typed extensible lists like this), there are no events.
In this case I would recommend switching the logic. Closing the form should remove it from the collection (you can't do anything with it anyway), which you can do by hooking onto the form's
FormClosed[
^] event:
List<Form> test = new List<Form>();
void Add(){
Form2 form2 = new Form2();
form2.FormClosed += (s,e) => test.Remove((Form)sender);
}
Then, you can cause a form to be removed by closing it, which will cause FormClosed to fire (if the close is allowed to happen) and thus the form to be removed from the list:
void RemoveFirst(){
test[0].Close();
}