So I think I have figured out what causes the issue and have a short term fix for my particular case. In this document some fields are sub type "Link", not "Widget" and the fix code I was using (based on link above which most likely came from here https://kb.itextsupport.com/home/it7kb/faq/why-are-the-acrofields-in-my-document-empty) will fail. My fix is is to skip sub type link, although perhaps a better solution exists that would not skip Links, which I don't need.
If I don't skip Links, when the saved PDF is loaded again it fails on
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
In the lower level code in itext.forms, IterateFields() is called and within that it passes formField.GetParent() as a parameter to
PdfFormField.MakeFormField, GetParent() returns null for the Link fields so there is an exception.
Below is the RUPS hierarchy to the first subtype Link field that causes a problem

So the solution at the moment to fix my particular issue is to skip sub type links. The code is as follows
PdfReader reader = new PdfReader(pdf);
MemoryStream dest = new MemoryStream();
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfCatalog root = pdfDoc.GetCatalog();
PdfDictionary form = root.GetPdfObject().GetAsDictionary(PdfName.AcroForm);
PdfArray fields = form.GetAsArray(PdfName.Fields);
if (fields == null)
{
form.Put(PdfName.Fields, new PdfArray());
fields = form.GetAsArray(PdfName.Fields);
}
for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++)
{
PdfPage page = pdfDoc.GetPage(i);
var annots = page.GetAnnotations();
for (int j = 0; j < annots.Count(); j++)
{
PdfObject o = annots[j].GetPdfObject();
PdfDictionary m = o as PdfDictionary;
string subType = m?.GetAsName(PdfName.Subtype)?.GetValue() ?? "";
if (subType != "Link")
{
fields.Add(o);
fields.SetModified();
}
}
}
pdfDoc.Close();