First thing that comes to my mind is to leave constructors as they are and add Init procedure with dofferent parameters. So the code would look like this.
[pascal]
type
TClass1 = class;
TClass1Object = class of TClass1; //a class object (metaclass)

TClass1 = class(TObject)
...
constructor Create; virtual;
procedure Init; virtual;
function AddIt(classType : TClass1Object): TClass1;
...
end;

TClass2 = class(TClass1)
...
constructor Create; override; //must have same signature as TClass1.Create
procedure Init(const s : string); reintroduce;
end;

...

function TClass1.AddIt(classType : TClass1Object): TClass1;
begin
Result := classType.Create;
FList.Add(Result)
end;

procedure TClass1.Init;
begin
writeln('Simple init');
end;

...

procedure TClass2.Init(const s : string);
begin
writeln('Init '+s);
end;

var
C,C1: TClass1;
begin
C := TClass1.Create();
try
C.X := 3.14;
C1 := C.AddIt(TClass2);
if C1 is TClass2 then
(C1 as TClass2).Init('C1')
else
C1.Init;
C1.X := 5.25;
WriteVal();
finally
FreeAndNil(C);
end;

readln;
end.
[/pascal]
But there is a problem with the if statement. If You add another class (TClass3) with another version of Init then You need to update the if statement. That is why constructors (and init functions) should have same signature. The only way to fix it that I can think of, is to use some flexible data format which can hold different data types. This could be XML, JSON or your own custom data format. So the code would be like this.
[pascal]
type
TClass1 = class;
TClass1Object = class of TClass1; //a class object (metaclass)

TClass1 = class(TObject)
...
constructor Create; virtual;
procedure Init(data : TXMLNode); virtual;
function AddIt(classType : TClass1Object): TClass1;
...
end;

TClass2 = class(TClass1)
...
constructor Create; override;//must have same signature as TClass1.Create
procedure Init(data : TXMLNode); override;
end;

...

function TClass1.AddIt(classType : TClass1Object): TClass1;
begin
Result := classType.Create;
FList.Add(Result)
end;

procedure TClass1.Init(data : TXMLNode);
begin
//do something with data
end;
...

procedure TClass2.Init(data : TXMLNode);
begin
//do something else with data
end;

var
C: TClass1;
data : TXMLNode;
begin
loadData(data); //get data
C := TClass1.Create();
C.Init(nil);
try
C.X := 3.14;
with C.AddIt(TClass2) do //type casting is not needed anymore
begin
X := 5.25;
Init(data);
WriteVal();
end;
finally
FreeAndNil(C);
end;

readln;
end.
[/pascal]
Of cousrse, the Init procedure can be integrated into the AddIt function.
[EDIT] I've corrected the code as pointed by Michalis.