You've allocated your 2-D matrix on the heap, and you're using a Square** to access it.  This means that you've: (1) allocated the space for each element in one or more calls to malloc, and (2) allocated the space for all of the row pointers in a call to malloc.  How to proceed depends quite a lot of how you've allocated the array.
Below, I use assert to stress that each malloc/realloc can return NULL (indicating that it could not complete the request).  You'll probably want to handle these cases properly.
Option 1: You allocated each row separately
You allocated the s1 matrix like this:
Square** s1 = malloc(M1*sizeof(s1[0]));
for (size_t i=0; i < M1; i++)
  s1[i] = malloc(N1*sizeof(s1[i][0]));
In this case, you have to handle each row separately:
/* M1 and N1 set to size of s1 (M1 x N1) */
/* M2 and N2 set to size of s2 (M2 x N2) */
/* First, reallocate the pointers to each row */
Square** tmpRows = realloc(s1, M2*sizeof(*tmpRows));
assert( (tmpRows != NULL) && "Out of memory reallocating rows" );
s1 = tmpRows;
/* Now, reallocate each row */
for (size_t i=0; i < M1; i++) {
  Square* tmpVals = realloc(s1[i], N2*sizeof(tmpVals[0]));
  assert( (tmpVals != NULL) && "Out of memory reallocating row" );
  /* copy elements of s2 into new column */
  memcpy(tmpVals+N1, s2[i]+N1, (N2-N1)*sizeof(s1[i][0]));
  s1[i] = tmpVals;
}
/* Now, allocate each new row of s1 and copy the additional rows of s2 into s1 */
for (size_t i=M1; i < M2; i++) {
  s1[i] = malloc( N2 * sizeof(s1[i][0]) );
  assert( (s1[i] != NULL) && "Out of memory allocating new row" );
  memcpy(s1[i], s2[i], N2*sizeof(s1[i][0]));
}
Option 2: You allocated each all of the rows at once
In this case, you allocated all of the rows in one big chunk, and then assigned pointers to the beginning of each row.  Like this:
Square** s1 = malloc(M1*sizeof(s1[0]));
s1[0] = malloc( M1*N1*sizeof(s1[0][0]) );
for(size_t i=1; i < M1; i++) 
  s1[i] = s1[i-1] + N1;
To resize the array (and initialize its new elements with those of s2), you should do the following:
/* M1 and N1 set to size of s1 (M1 x N1) */
/* M2 and N2 set to size of s2 (M2 x N2) */
/* Make a new copy of the elements of s1.  Linear layout of a 200x200 
 * matrix will be different than the linear layout of a 100x100 matrix.
 * Making a new copy makes it easier to initialize its values.
 */
Square* new_mat = malloc( M2*N2*sizeof(new_mat[0]) );
assert( (new_mat != NULL) && "Out of memory allocating new matrix" );
/* Initialize with values of s2.  Assumption: s2 is also allocated
 * as a contiguous array...
 */
memcpy(new_mat, s2[0], M2*N2*sizeof(s2[0][0]));
/* Now, reallocate the rows */
Square** tmpRows = realloc(s1, M2*sizeof(s1[0]));
assert( (tmpRows != NULL) && "Out of memory reallocating rows" );
s1 = tmpRows;
/* Copy data from old rows into new rows... */
for (size_t i=0; i < M1; i++) {
  /* rows of s1 still point to old_mat data, copy it into new_mat.
   * Each row in new_mat starts at (new_mat + N2*i)
   */
  memcpy( new_mat + N2*i, s1[i], N1*sizeof(s1[i][0]) );
}
/* Free old memory and assign new row pointers... */
free(s1[0]);
s1[0] = new_mat;
for (size_t i=1; i < M2; i++)
  s1[i] = s1[i-1] + N2;