conca (h:t) result = conca (init (h:t)) ( last(h:t):result )
is a tail call, but last(h:t):result starts life as an unevaluated thunk, so it's a (hand-wavy) bit like these nested function calls are on the stack still.
conca pattern matches on its first argument so init will be evaluated in the recursive call.
conca is non-strict in its second argument, so those thunks won't get evaluated while applying the recursive call of conca.
remov is tail recursive, yes, but....
Use True and False instead of 0 and 1 to make your code clearer:
remov n [] found result = invert result []
remov n (h:t) found result
| found = remov n t True (h:result)
| n==h = remov n t True (result)
| otherwise = remov n t False (h:result)
remove n list = remov n list False []
This would be better not passing around so much data, reducing the copying of n and using two functions instead of a single function that tests a boolean parameter:
remove' n list = seek list [] where
seek [] result = invert result []
seek (h:t) result | h == n = got t result
| otherwise = seek t (h:result)
got [] result = invert result []
got (h:t) result = got t (h:result)
but got a result just calculates reverse result ++ a, so you could write
remove'' n list = seek list [] where
seek [] result = invert result []
seek (h:t) result | h == n = invert result [] ++ t
| otherwise = seek t (h:result)
However, it all seems rather a lot of effort, and still traverses the list twice. Why not go for a non-tail call:
removeFast n [] = []
removeFast n (h:t) | h == n = t
| otherwise = h:removeFast n t
This has the benefit of producing its first element straight away rather than running the whole list, and short cuts to return t without further computation once it's found the element to remove. Try racing length (removeFast 1 [1..100000]) against length (remove 1 [1..100000]) (vary the number of zeros according to your processor speed).
If you want to make a more efficient tail recursive conca, you could use the trick from remove:
conc this result = prepend (invert this []) result
prepend [] result = result
prepend (h:t) result = prepend t (h:result)
As before, you're traversing this twice, once inverting it, the other prepending it, but that's still a linear algorithm, and much better than using init and last for each element, which is quadratic.