"Early bird" squares

JavaScript (ES6), 51 49 45 bytes

1-indexed.

f=(n,s=k='')=>n?f(n-!!s.match(++k*k),s+k*k):k

Demo

f=(n,s=k='')=>n?f(n-!!s.match(++k*k),s+k*k):k

for(n = 1; n <= 20; n++) {
  console.log('a(' + n + ') = ' + f(n))
}

Formatted and commented

f = (                         // f = recursive function taking:
  n,                          //   n = input
  s = k = ''                  //   s = string of concatenated squares, k = counter
) =>                          //
  n ?                         // if we haven't reached the n-th term yet:
    f(                        //   do a recursive call with:
      n - !!s.match(++k * k), //     n decremented if k² is an early bird square
      s + k * k               //     s updated
    )                         //   end of recursive call
  :                           // else:
    k                         //   return k

Non-recursive version, 53 bytes

This one does not depend on your engine stack size.

n=>{for(k=s='';n-=!!(s+=k*k).match(++k*k););return k}

Try it online!


Pyth, 12 bytes

e.f/jk^R2Z`*

Try it here!

How it works

e.f/jk^R2Z`* ~ Full program. Let Q be our input.

 .f          ~ First Q positive integers with truthy results. Uses the variable Z.
      ^R2Z   ~ Square each integer in the range [0, Z).
    jk       ~ Concatenate into a single string.
   /         ~ Count the occurrences of...
          `* ~ The string representation of Z squared.
               Yields 0 if falsy and ≥ 1 if truthy.
e            ~ Get the last element (Qth truthy integer). Output implicitly.

05AB1E, 10 9 bytes

Saved 1 byte thanks to Adnan.

µNL<nJNnå

Try it online!

Explanation

µ           # loop until counter equals the input
 NL         # push the range [1 ... iteration_no]
   <        # decrement each
    n       # square each
     J      # join to string
      Nnå   # is iteration_no in the string?
            # if true, increase counter