SWI-Prolog allows this compact implementation.
square_sum(N,L) :- numlist(1,N,T), select(D,T,R), adj_squares(R,[D],L). adj_squares([],L,R) :- reverse(L,R). adj_squares(T,[S|Ss],L) :- select(D,T,R), float_fractional_part(sqrt(S+D))=:=0, adj_squares(R,[D,S|Ss],L).
which is very fast when N = 15
edit as suggested, building the list in order gives the best code:
square_sum(N,L) :- numlist(1,N,T), select(D,T,R), adj_squares(R,D,L). adj_squares([],L,[L]). adj_squares(T,S,[S|L]) :- select(D,T,R), float_fractional_part(sqrt(S+D))=:=0, adj_squares(R,D,L).
change
the above code gets too slow when N grows. I changed the strategy and try to find the Hamilton path to the graph induced by the binary relation. For N = 15, it looks like

(here is the code to create the Graphviz script:
square_pairs(N,I,J) :- between(1,N,I), I1 is I+1, between(I1,N,J), float_fractional_part(sqrt(I+J))=:=0. square_pairs_graph(N) :- format('graph square_pairs_N_~d {~n', [N]), forall(square_pairs(N,I,J), format(' ~d -- ~d;~n', [I,J])), writeln('}').
)
and here is the code for finding the path
hamiltonian_path(N,P) :- square_pairs_struct(N,G), between(1,N,S), extend_front(1,N,G,[S],P). extend_front(N,N,_,P,P) :- !. extend_front(Len,Tot,G,[Node|Ins],P) :- arg(Node,G,Arcs), member(T,Arcs), \+memberchk(T,Ins), Len1 is Len+1, extend_front(Len1,Tot,G,[T,Node|Ins],P). struct_N_of_E(N,E,S) :- findall(E,between(1,N,_),As), S=..[graph|As]. square_pairs_struct(N,G) :- struct_N_of_E(N,[],G), forall(square_pairs(N,I,J), (edge(G,I,J),edge(G,J,I))). edge(G,I,J) :- arg(I,G,A), B=[J|A], nb_setarg(I,G,B).