Not sure why you are not just using your "Working Fine" solution...
If you want to use two loops for some reason, then you need to create the wrapper in the outer loop once only and collect the Contacts in the inner loop on that wrapper. Here is one way to do that:
for(Account accRec : accSearch) {
WrapperAcc w = new WrapperAcc(accRec);
wrapperLst.add(w);
for (Contact gpa : accRec.contacts) {
w.addGpa(gpa);
}
}
public class WrapperAcc {
public Account acc {get; private set;}
public List<Contact> gpaList {get; private set;}
WrapperAcc(Account acc) {
this.acc = acc;
this.gpaList = new List<Contact>();
}
void addGpa(Contact gpa) {
gpaList.add(gpa);
}
}
Note that at the moment the wrapper serves no purpose because your query results include the relationship list and so the page can work directly from those results:
<apex:pageBlock>
<apex:repeat value="{!accSearch}" var="a">
<apex:pageBlockSection title="{!a.Name}"/>
<apex:pageBlockTable value="{!a.Contacts}" var="c">
<apex:column headerValue="Name">
{!c.name}
</apex:column>
</apex:pageBlockTable>
</apex:repeat>
</apex:pageBlock>
Wrapper classes are needed if you want to apply presentation methods to the data such as extra formatting, or to add extra data such as selected flags, or adapt differing data to a single presentation, or present related data where the data can't be queried in a single query.