Some basic things which i didn't knew in the begining :
Fast persistent data structures - Coming from imperative langs, one might be hesitant to write functions which take a million elt vector, modify it and return a new vector. It is important to know that any good implementation of functional data structures will allow you to do this in constant time & speed. (independent of the size of the data structure).
Editor combinators : If you arent aware of this & are modifying a data structure with several levels of nesting, imperative assignment will seem much more convenient, ie dont translate foo.bar=3, into something of this pattern barNew = editVector(foo.bar, 8, 3), fooNew=editMap(foo, "bar", barNew). It gets worse with more levels. Instead, use an editor-combinator library which will allow to you specify the path within the data-structure and a new value just as in the imperative case.
Things to know which are not strictly FP related, but nevertheless very useful - pattern matching simplifies definitions a lot, typeclasses are usually more convenient than class hierarchies.
Someone has already pointed out advice on libraries, (Clojure or any using any popular language in a functional way).
The main thing which motivates all of this - composability. It is hard to combine procedures with side effects into compound procedures because one needs to keep track of whether the component procedures are interfering with each other. FP eliminates this friction in composition.