Let's analyse your questions.
Q 1. OS runs in kernel mode and schedules processes for execution. Then we go to user mode and our code of process is executed. Then somehow we go back to kernel mode and next process is scheduled for execution.
Ans: Sometimes it's not only kernel scheduler schedules user threads for executions, it also involves schedulers in user space too. Because of this conflict, problem of priority inversion comes into picture, researchers are still working on it to find effective solution. So to schedule your thread there is no need for your thread to go to kernel mode. Scheduler in kernel will take care of it as it has list of all threads/processes running in the system. Your thread will go into kernel mode only if it requires any service from kernel apart from scheduling. So basically, to execute your thread there is no need to go to kernel, mode switching is very costly in the perspective of time and space, as kernel should store the stack frame of user thread in the kernel stack. Switching between user and kernel should be avoided as much as possible.
Q 2: I've read that system calls (for example: requests to access filesystem) cause CPU to go back to kernel mode. However let's say that there is this code:
for(int i = 0; i > -1; ++i);
which will take much time and it looks like that no system calls will be done here.
What does cause that processor is switched back from user mode to kernel mode? Some timeouts?
Ans: Each user and kernel threads of some time quantum which is set depending on the kernel. If that thread exceeds it's execution time scheduler will preempt current running thread in the cpu and schedules another thread from the run queue. As there are number of algorithms for how to schedule the threads in CPU and different system follows different approaches suitable for the requirement.
Since your code takes more time than the allocated quantum scheduler will preempt your thread and schedules other. Other thread may be user level thread or kernel thread. Hence you can see one or more kernel threads running after it preempts your thread. It is not necessary to switch to kernel threads. It all depends on the priority.
I hope I answered your question upto some extent.